package com.cy.pj.common.config;


import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;

@Configuration
public class SpringShiroConfig {
    //配置session回话时长
    @Bean
    public DefaultWebSessionManager sessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        //设置过期时间为2个小时，默认为30分钟
        sessionManager.setGlobalSessionTimeout(2*60*60*1000);
        return sessionManager;
    }

    //配置shiro中的核心对象：安全管理器--负责认证，授权等业务实现
    @Bean
    public SecurityManager securityManager(Realm realm,
                                           DefaultWebSessionManager sessionManager){
        DefaultWebSecurityManager sManager =
                new DefaultWebSecurityManager();
        sManager.setRealm(realm);
        //设置自定义登录时长管理
        sManager.setSessionManager(sessionManager);
        return sManager;
    }

    //配置ShiroFilterFactoryBean，基于此对象创建过滤器工厂，
    //通过此对象设置资源匿名访问、认证访问
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactory (SecurityManager securityManager){
        ShiroFilterFactoryBean sfBean =
                new ShiroFilterFactoryBean();
        sfBean.setSecurityManager(securityManager);
        //假如没有认证请求先访问此认证的url
        sfBean.setLoginUrl("/doLoginUI");
        //定义map指定请求过滤规则(哪些资源允许匿名访问,哪些必须认证访问)
        LinkedHashMap<String,String> map = new LinkedHashMap<>();
        //静态资源允许匿名访问:"anon"--框架定义的
        //需要先定义匿名的访问，所有使用LinkedHashMap这个有序的map
        map.put("/bower_components/**", "anon");
        map.put("/build/**","anon");
        map.put("/dist/**","anon");
        map.put("/plugins/**", "anon");
        map.put("/user/doLogin", "anon");
        map.put("/doLogout", "logout");

        //除了静态资源外，其它都要认证("authc")后访问
        map.put("/**","authc");
        sfBean.setFilterChainDefinitionMap(map);
        return sfBean;
    }

    //==========================Shiro框架授权配置====================
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return  new LifecycleBeanPostProcessor();
    }
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        return new DefaultAdvisorAutoProxyCreator();
    }

    //配置advisor对象,shiro框架底层会通过此对象的matchs方法返回值(类似切入点)
    //决定是否创建代理对象,进行权限控制
    @Bean
    public AuthorizationAttributeSourceAdvisor
    authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor advisor =
                new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }


}
